/**
 * Label représentant une touche du clavier
 * 
 * @author Marie-Hélène Goddet, Damien Finck, Cédric Schaller
 * 
 */
package gui;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;

@SuppressWarnings("serial")

public class JTouche extends JLabel {
	//Variables globales
	private boolean enfonce;
	private int mode;
	private boolean lock;
	
	static int TOUCHE_STANDARD=1;
	static int TOUCHE_ACTION=2;
	static int TOUCHE_ACTION_WITH_LOCK=3;
	
	private ActionListener actionListener;
	
	//Constructeurs
	/**
	 * Constructeur
	 * @param text texte à afficher dans la touche
	 * @param alignment endroit où placer la lettre
	 * @param mode mode de la touche (TOUCHE_STANDARD, TOUCHE_ACTION ou TOUCHE_ACTION_WITH_LOCK)
	 */
	public JTouche(String text, int alignment, int mode) {
		this(text, null, alignment, mode);
	}
	/**
	 * Constructeur
	 * @param icon l'icone à afficher sur la touche
	 * @param mode le mode de la touche
	 */
	public JTouche(Icon icon, int mode) {
		this(null, icon, SwingConstants.LEFT, mode);
	}
	/**
	 * Constructeur
	 * @param icon l'icone à afficher sur la touche
	 * @param alignment l'endroit où placer la touche
	 * @param mode le mode de la touche
	 */
	public JTouche(Icon icon, int alignment, int mode) {
		this(null, icon, alignment, mode);
	}
	/**
	 * Constructeur appelé par les autres constructeurs
	 * @param text
	 * @param icon
	 * @param alignment
	 * @param mode
	 */
	public JTouche(String text, Icon icon, int alignment, int mode) {
		/** Evénements **/
		MouseListener mouse = new Event_JTouche(this);
		this.addMouseListener(mouse);
		/** Paramètres **/
		Font f = new Font("Default",Font.BOLD,24);
		this.setFont(f);
		this.setText(text);
		this.setIcon(icon);
		this.setHorizontalAlignment(alignment);
		this.setMode(mode);
		this.setEnfonce(false);
		this.setLock(false);
		
		//super.paint(this.getGraphics());
		this.setForeground(Color.BLACK);
		this.setBackground(Color.GRAY);
		//this.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		
		this.addActionListener(null);
	}
	
	//Acesseurs
	/**
	 * Indique si la touche doit etre enfoncée ou non
	 * @param enfonce true si la touche doit etre enfoncée false sinon
	 */
	public void setEnfonce(boolean enfonce) {
		if (enfonce)
			this.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		else
			this.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		this.enfonce = enfonce;
	}
	/**
	 * Indique si la touche est enfoncée
	 * @return true si la touche est enfoncée false sinon
	 */
	public boolean isEnfonce() {
		return enfonce;
	}
	/**
	 * Indique le mode de la touche 
	 * @param mode mode de la touche (TOUCHE_STANDARD, TOUCHE_ACTION ou TOUCHE_ACTION_WITH_LOCK)
	 */
	public void setMode(int mode) {
		this.mode = mode;
	}
	/**
	 * Retourne le mode de la touche
	 * @return le mode de la touche
	 */
	public int getMode() {
		return mode;
	}
	public void setLock(boolean lock) {
		this.lock = lock;
	}
	public boolean isLock() {
		return lock;
	}
	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
	}
	public boolean isEnabled() {
		return super.isEnabled();
	}
	public void addActionListener(ActionListener actionListener) {
		this.actionListener = actionListener;
	}
	public ActionListener getActionListener() {
		return actionListener;
	}
	
	//Autres méthodes
	public void paint(Graphics g) {
		g.setColor(Color.LIGHT_GRAY);
		Rectangle r = g.getClipBounds();
		//g.fillRoundRect(r.x, r.y, r.width, r.height,50,50);
		//g.fillOval(r.x, r.y, r.width, r.height);
		g.fillRect(r.x, r.y, r.width, r.height);
		super.paint(g);
	}
}
class Event_JTouche implements MouseListener {
	JTouche jp;
	/**
	 * Constructeur
	 * @param jp le label de la touche
	 */
	public Event_JTouche(JTouche jp) {
		this.jp=jp;
	}
	/**
	 * Appelée si on appuie sur la touche
	 */
	@Override
	public void mouseClicked(MouseEvent arg0) {
		Object obj = arg0.getSource();
		if (obj instanceof JTouche) {
			JTouche jt = (JTouche)obj;
			if (jt.isEnabled()) { // si la touche n'est pas vérouillée
				if (jt.getMode()==JTouche.TOUCHE_STANDARD) {
					if (jp.getActionListener()!=null) {
						ActionEvent e = new ActionEvent(jp,1,"JTouche_clicked");
						jp.getActionListener().actionPerformed(e);
					}
				} else if (jt.getMode()==JTouche.TOUCHE_ACTION) {
					if (jp.getActionListener()!=null) {
						ActionEvent e = new ActionEvent(jp,1,"JTouche_clicked");
						jp.getActionListener().actionPerformed(e);
					}
				} else if (jt.getMode()==JTouche.TOUCHE_ACTION_WITH_LOCK) {
					// l'évènements n'est pas définit ici (voir mouseReleased())
				}
			}
		}
	}
	@Override
	public void mouseEntered(MouseEvent arg0) {
		
	}
	@Override
	public void mouseExited(MouseEvent arg0) {
		
	}
	/**
	 * Appelée lors du début de swype sur la touche
	 */
	@Override
	public void mousePressed(MouseEvent arg0) {
		Object obj = arg0.getSource();
		if (obj instanceof JTouche) {
			JTouche jt = (JTouche)obj;
			if (jt.isEnabled()) { // si la touche n'est pas vérouillé
				if (jt.getMode()==JTouche.TOUCHE_STANDARD) {
					jt.setEnfonce(true);
				} else if (jt.getMode()==JTouche.TOUCHE_ACTION)
					jt.setEnfonce(true);
				else if (jt.getMode()==JTouche.TOUCHE_ACTION_WITH_LOCK) {
					jt.setEnfonce(true);
				}
			}
		}
	}
	/**
	 * Appelée lors du relâchement de la touche
	 */
	@Override
	public void mouseReleased(MouseEvent arg0) {
		Object obj = arg0.getSource();
		if (obj instanceof JTouche) {
			JTouche jt = (JTouche)obj;
			if (jt.isEnabled()) { // si la touche n'est pas vérouillé
				if (jt.getMode()==JTouche.TOUCHE_STANDARD) {
					jt.setEnfonce(false);
				} else if (jt.getMode()==JTouche.TOUCHE_ACTION)
					jt.setEnfonce(false);
				else if (jt.getMode()==JTouche.TOUCHE_ACTION_WITH_LOCK) {
					if (jt.isLock()) jt.setEnfonce(false);
					if (jt.isEnfonce()) jt.setLock(true); else jt.setLock(false);
					
					// ici pas dans clicked; parce que clicked n'est pas exécuté si on sort du bouton pour released.
					// et comme le design a déjà indiqué au user que je fais l'evenement, ben je le fais !
					if (jp.getActionListener()!=null) {
						ActionEvent e = new ActionEvent(jp,1001,"JTouche_released");
						jp.getActionListener().actionPerformed(e);
					}
				}
			}
		}
	}
}